package com.simple.editor.ui;

import com.simple.editor.action.ActionManager;
import com.simple.editor.action.EditorException;

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

/**
 * {@link TabbedEditorPane} provides working area (editors panels)
 * <p/>
 * Created with IntelliJ IDEA.
 * User: vlad
 * Date: 6/2/13
 * Time: 2:11 PM
 * To change this template use File | Settings | File Templates.
 */
public class TabbedEditorPane extends JPanel {

    private final Map<String, Tab> openFiles;
    private final ActionManager actionManager;
    private final JTabbedPane tabbedPane;

    public TabbedEditorPane(final ActionManager actionManager) {
        this.actionManager = actionManager;
        openFiles = new HashMap<String, Tab>();

        tabbedPane = new JTabbedPane();
        tabbedPane.setPreferredSize(new Dimension(500, 300));
        tabbedPane.setTabLayoutPolicy(JTabbedPane.WRAP_TAB_LAYOUT);
        final JScrollPane scrollPane = new JScrollPane();
        final JTextArea textArea = createTextArea();

        textArea.setEditable(false);
        textArea.setColumns(20);
        textArea.setLineWrap(true);
        textArea.setRows(5);
        final String aboutText = new Scanner(TabbedEditorPane.class.getResourceAsStream("/About.txt")).useDelimiter("\\Z").next();
        textArea.setText(aboutText);
        scrollPane.setViewportView(textArea);

        tabbedPane.addTab("About", scrollPane);

        setLayout(new GridLayout());
        add(tabbedPane, BorderLayout.CENTER);
    }

    private static JTextArea createTextArea() {
        final JTextArea textArea = new JTextArea();
        final Font font = new Font("Verdana", Font.PLAIN, 12);
        textArea.setFont(font);
        textArea.setForeground(Color.DARK_GRAY);
        return textArea;
    }

    public void syncEditorFromDisk(final FileModel file) throws EditorException {
        final Tab tab = openFiles.get(file.getAbsolutePath());
        if (tab != null) {
            tab.readFile();
            file.setChanged(false);
        }
    }

    public boolean openFile(final FileModel file) throws EditorException {
        final boolean newFile;

        Tab tab = openFiles.get(file.getAbsolutePath());
        if (tab == null) {
            newFile = true;
            tab = new Tab(file, actionManager);
            tab.readFile();

            openFiles.put(file.getAbsolutePath(), tab);
            // Add the tab to the pane without any label
            tabbedPane.addTab(null, tab);
            final int pos = tabbedPane.indexOfComponent(tab);
            // Now assign the component for the tab
            tabbedPane.setTabComponentAt(pos, tab.getPnlTab());

            // Bring the new tab to the front
            setSelectedTab(tab);
        } else {
            newFile = false;
            tabbedPane.setSelectedComponent(tab);
        }
        return newFile;
    }

    public void closeTab(final FileModel... files) {

        for (FileModel file : files) {
            final Tab tab = openFiles.get(file.getAbsolutePath());
            if (tab != null) {
                tabbedPane.remove(tab);
                openFiles.remove(file.getAbsolutePath());
            }
        }
    }

    public void saveTab(final FileModel... files) {

        for (FileModel file : files) {
            final Tab tab = openFiles.get(file.getAbsolutePath());
            try {
                if (tab != null && tab.save()) {
                    syncLabelStyle(file);
                }
            } catch (EditorException e) {
                e.printStackTrace();
            }
        }
    }

    public FileModel[] saveAllTabs() throws EditorException {
        java.util.List<FileModel> fileModelList = new ArrayList<FileModel>();
        for (final Tab tab : openFiles.values()) {
            if (tab.save()) {
                fileModelList.add(tab.getFile());
            }
        }
        return fileModelList.toArray(new FileModel[fileModelList.size()]);
    }

    public boolean isOpened(final String tabId) {
        return openFiles.containsKey(tabId);

    }

    public void syncLabelStyle(final FileModel... files) {
        for (final FileModel file : files) {
            final Tab tab = openFiles.get(file.getAbsolutePath());
            if (tab != null) {
                // update VCS status for recently opened file,
                // since the tab will have another FileModel instance for reopened file
                tab.getFile().setStatus(file.getStatus());
                tab.syncLabelStyle();
            }
        }
    }

    private void setSelectedTab(final Tab tab) {
        tabbedPane.setSelectedComponent(tab);
    }
}
